package com.framework.bdf4j.sysadm.controller;

import java.util.Date;
import java.util.List;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.framework.bdf4j.annotations.SysLog;
import com.framework.bdf4j.comm.Constants;
import com.framework.bdf4j.comm.persist.PageDomain;
import com.framework.bdf4j.comm.util.R;
import com.framework.bdf4j.comm.util.StringUtils;
import com.framework.bdf4j.sysadm.entity.SysDict;
import com.framework.bdf4j.sysadm.entity.SysDictItem;
import com.framework.bdf4j.sysadm.service.SysDictItemService;
import com.framework.bdf4j.sysadm.service.SysDictService;
import com.framework.bdf4j.sysadm.vo.Ztree;

import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;

/**
 * <p>
 * 字典表 前端控制器
 * </p>
 *
 */
@Controller
@AllArgsConstructor
@RequestMapping("/admin/dict")
@Api(value = "dict", tags = "字典管理模块")
public class SysDictController {
    private final SysDictService sysDictService;
    private final SysDictItemService sysDictItemService;

    // 跳转到字典列表页
    @GetMapping("/index")
    public String goDict() {
        return "sysadm/dict/dictList";
    }

    // 跳转到字典编辑页
    @GetMapping("/goEditDict")
    public String goEditDict(@RequestParam(required = false) String id, @RequestParam String oper, Model model) {
        SysDict dict = new SysDict();
        if (!"add".equals(oper)) {
            dict = sysDictService.getById(Integer.parseInt(id));
        }
        model.addAttribute("viewobject", dict);
        model.addAttribute("oper", oper);
        return "sysadm/dict/dictEdit";
    }

    /**
     * 分页查询字典信息
     *
     * @param page
     *            分页对象
     * @return 分页对象
     */
    @ResponseBody
    @GetMapping("/page")
    public R<IPage> getDictPage(Page page, PageDomain domain, SysDict sysDict) {
        OrderItem orderitem = StringUtils.getOrderItem(domain);
        if (orderitem != null) {
            page.addOrder(orderitem);
        }
        return R.ok(sysDictService.page(page, Wrappers.query(sysDict)));
    }

    /**
     * 添加字典
     *
     * @param sysDict
     *            字典信息
     * @return success、false
     */
    @SysLog("添加字典")
    @ResponseBody
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys_dict_add')")
    public R save(SysDict sysDict) {
        // 字典编码判重
        List<SysDict> dictlist = sysDictService.list(Wrappers.<SysDict>query().lambda()
            .eq(SysDict::getType, sysDict.getType()).eq(SysDict::getDelFlag, Constants.STATUS_NORMAL));

        if (CollectionUtils.isNotEmpty(dictlist)) {
            return R.failed("字典编码不能重复");
        }
        return R.ok(sysDictService.save(sysDict));
    }

    /**
     * 删除字典，并且清除字典缓存
     *
     * @param id
     *            ID
     * @return R
     */
    @SysLog("删除字典")
    @ResponseBody
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('sys_dict_del')")
    public R removeById(@PathVariable Integer id) {
        return sysDictService.removeDict(id);
    }

    /**
     * 修改字典
     *
     * @param sysDict
     *            字典信息
     * @return success/false
     */
    @PutMapping
    @ResponseBody
    @SysLog("修改字典")
    @PreAuthorize("@pms.hasPermission('sys_dict_edit')")
    public R updateById(SysDict sysDict) {
        // 字典编码判重
        List<SysDict> dictlist =
            sysDictService.list(Wrappers.<SysDict>query().lambda().eq(SysDict::getType, sysDict.getType())
                .eq(SysDict::getDelFlag, Constants.STATUS_NORMAL).ne(SysDict::getId, sysDict.getId()));

        if (CollectionUtils.isNotEmpty(dictlist)) {
            return R.failed("字典编码不能重复");
        }
        return sysDictService.updateDict(sysDict);
    }

    /**
     * 查询字典详细
     */
    @GetMapping("/detail/{dictId}")
    public String detail(@PathVariable("dictId") Integer dictId, ModelMap mmap) {
        mmap.put("dict", sysDictService.getById(dictId));
        return "sysadm/dict/dictItemList";
    }

    /**
     * 分页查询
     *
     * @param page
     *            分页对象
     * @param sysDictItem
     *            字典项
     * @return
     */
    @ResponseBody
    @GetMapping("/item/page")
    public R getSysDictItemPage(Page page, SysDictItem sysDictItem) {
        return R.ok(sysDictItemService.page(page, Wrappers.query(sysDictItem).orderByAsc("sort")));
    }

    // 跳转到字典数据编辑页
    @GetMapping("/item/goEditDictItem")
    public String goEditDictItem(@RequestParam(required = false) String id, @RequestParam String oper, Model model) {
        SysDictItem dictItem = new SysDictItem();
        if (!"add".equals(oper)) {
            dictItem = sysDictItemService.getById(Integer.parseInt(id));
        } else {
            dictItem.setDictId(Integer.valueOf(id));
            dictItem.setType(sysDictService.getById(Integer.parseInt(id)).getType());
        }
        model.addAttribute("viewobject", dictItem);
        model.addAttribute("oper", oper);
        return "sysadm/dict/dictItemEdit";
    }

    /**
     * 新增字典项
     *
     * @param sysDictItem
     *            字典项
     * @return R
     */
    @SysLog("新增字典项")
    @ResponseBody
    @PostMapping("/item")
    @CacheEvict(value = Constants.DICT_DETAILS, allEntries = true)
    @PreAuthorize("@pms.hasPermission('sys_dict_add')")
    public R save(SysDictItem sysDictItem) {
    	// 字典编码判重
        List<SysDictItem> dictlist =
        		sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictId, sysDictItem.getDictId())
                .eq(SysDictItem::getDelFlag, Constants.STATUS_NORMAL).eq(SysDictItem::getValue, sysDictItem.getValue()));

        if (CollectionUtils.isNotEmpty(dictlist)) {
            return R.failed("字典值不能重复");
        }
        return R.ok(sysDictItemService.save(sysDictItem));
    }

    /**
     * 修改字典项
     *
     * @param sysDictItem
     *            字典项
     * @return R
     */
    @SysLog("修改字典项")
    @ResponseBody
    @PutMapping("/item")
    @PreAuthorize("@pms.hasPermission('sys_dict_edit')")
    public R updateById(SysDictItem sysDictItem) {
    	// 字典编码判重
        List<SysDictItem> dictlist =
        		sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictId, sysDictItem.getDictId())
                .eq(SysDictItem::getDelFlag, Constants.STATUS_NORMAL).ne(SysDictItem::getId, sysDictItem.getId()).eq(SysDictItem::getValue, sysDictItem.getValue()));

        if (CollectionUtils.isNotEmpty(dictlist)) {
            return R.failed("字典值不能重复");
        }
    	sysDictItem.setUpdateTime(new Date());
        return sysDictItemService.updateDictItem(sysDictItem);
    }

    /**
     * 通过id删除字典项
     *
     * @param id
     *            id
     * @return R
     */
    @SysLog("删除字典项")
    @ResponseBody
    @DeleteMapping("/item/{id}")
    @PreAuthorize("@pms.hasPermission('sys_dict_del')")
    public R removeDictItemById(@PathVariable Integer id) {
        return sysDictItemService.removeDictItem(id);
    }

    /**
     * 选择字典树
     */
    @GetMapping("/selectDictTree/{columnId}/{dictType}")
    public String selectDictTree(@PathVariable("columnId") Long columnId, @PathVariable("dictType") String dictType,
        ModelMap mmap) {
        mmap.put("columnId", columnId);
        mmap.put("dict", sysDictService.getOne(Wrappers.<SysDict>query().lambda().eq(SysDict::getType, dictType)));
        return "sysadm/dict/tree";
    }

    /**
     * 加载字典列表树
     */
    @GetMapping("/treeData")
    @ResponseBody
    public List<Ztree> treeData() {
        List<Ztree> ztrees = sysDictService.selectDictTree(new SysDict());
        return ztrees;
    }
}
